﻿Imports Microsoft.DirectX.Direct3D

Namespace Characters

    Module mCharacterList

        'list of MirActor classes that define the other Characters
        Public lstCharacters As New List(Of Actor.MirActor)

        Public Sub ClearList()

            'clear the character list
            If lstCharacters.Count = 0 Then Exit Sub

            Do While lstCharacters.Count > 0

                lstCharacters(0).mHeadAnim.Destroy()
                lstCharacters(0).mHumAnim.Destroy()
                lstCharacters(0).mWeaponAnim.Destroy()
                lstCharacters.RemoveAt(0)

            Loop

        End Sub

        Public Function GetGenderFromID(ActorID As Long) As Gender

            'determine gender
            If ActorID = Player.PlayerID Then
                Return Player.PlayerSex
            Else
                Dim A As Actor.MirActor = Characters.GetCharacterFromID(ActorID)
                If A Is Nothing Then
                    Return EvoLib.Protocol.mProtocol.Gender.Male
                Else
                    Return A.ActorSex
                End If
            End If

        End Function

        Public Function GetCharacterFromID(ActorID As Long) As Actor.MirActor

            If ActorID = Player.PlayerID Then Return Nothing

            If lstCharacters.Count > 0 Then

                Dim c As Integer = lstCharacters.Count - 1
                For i As Integer = 0 To c

                    If lstCharacters(i).ActorID = ActorID Then
                        Return lstCharacters(i)
                    End If

                Next

            End If

            Return Nothing

        End Function

        Public Sub AddCharacter(ByRef info As EvoLib.Protocol.CharacterAddInfo)

            If info.ID_CHARACTER = Player.PlayerID Then Exit Sub

            If lstCharacters.Count > 0 Then

                Dim c As Integer = lstCharacters.Count - 1

                For i As Integer = 0 To c
                    If lstCharacters(i).ActorID = info.ID_CHARACTER Then Exit Sub
                Next

            End If

            Dim obj As New Actor.MirActor(info.ID_CHARACTER, info.playerinfo, info.Positioninfo, info.VitalPoints)

            lstCharacters.Add(obj)

        End Sub

        Public Sub RemoveCharacter(ByRef id As Integer)

            If lstCharacters.Count = 0 Then Exit Sub

            Dim c As Integer = lstCharacters.Count - 1

            For i As Integer = 0 To c

                If lstCharacters(i).ActorID = id Then
                    lstCharacters(i).mHeadAnim.Destroy()
                    lstCharacters(i).mHumAnim.Destroy()
                    lstCharacters(i).mWeaponAnim.Destroy()
                    lstCharacters.RemoveAt(i)
                    Exit For
                End If

            Next

        End Sub

        Public Sub HitCharacter(ByVal info As EvoLib.Protocol.CharacterHitInfo)

            If lstCharacters.Count = 0 Then Exit Sub

            Dim c As Integer = lstCharacters.Count - 1

            For i As Integer = 0 To c

                If lstCharacters(i).ActorID = info.CharacterID Then
                    Dim tmp As Actor.MirActor = lstCharacters(i)
                    Dim diff As Integer = info.VitalPoints.HP - tmp.VitalPoints.HP
                    If diff <> 0 Or Not info.IgnoreMiss Then
                        AddHitIndicator(tmp.lstHits, diff)
                    End If

                    tmp.VitalPoints = info.VitalPoints
                    lstCharacters(i) = tmp
                    Exit For
                End If

            Next

        End Sub

        Public Sub MoveCharacter(ByRef id As Integer, ByRef info As EvoLib.Protocol.PlayerPositionInfo)

            If lstCharacters.Count = 0 Then Exit Sub

            Dim c As Integer = lstCharacters.Count - 1
            Dim tmp As Actor.MirActor

            For i As Integer = 0 To c

                If lstCharacters(i).ActorID = id Then

                    tmp = lstCharacters(i)


                    Select Case (CType(info.BYTE_ANIM, EvoLib.Protocol.HUMAnimation))

                        Case EvoLib.Protocol.HUMAnimation.Standing
                            tmp.ChangeMovementDirection(info.BYTE_DIRECTION)
                            tmp.Stand(info)
                            tmp.mXCoord = info.INT2_X
                            tmp.mYCoord = info.INT2_Y

                        Case EvoLib.Protocol.HUMAnimation.Walking
                            tmp.ChangeMovementDirection(info.BYTE_DIRECTION)
                            tmp.Walk(info)

                        Case EvoLib.Protocol.HUMAnimation.Running
                            tmp.ChangeMovementDirection(info.BYTE_DIRECTION)
                            tmp.Run(info)

                        Case EvoLib.Protocol.HUMAnimation.GettingHit
                            tmp.Hit(info)

                        Case EvoLib.Protocol.HUMAnimation.Die
                            tmp.ChangeMovementDirection(info.BYTE_DIRECTION)
                            tmp.Die(info)
                            tmp.mXCoord = info.INT2_X
                            tmp.mYCoord = info.INT2_Y

                        Case EvoLib.Protocol.HUMAnimation.Attack
                            tmp.ChangeMovementDirection(info.BYTE_DIRECTION)
                            tmp.Attack(info)

                        Case EvoLib.Protocol.HUMAnimation.Cast1
                            tmp.ChangeMovementDirection(info.BYTE_DIRECTION)
                            tmp.Cast1(info)

                    End Select

                    'DoAnims(tmp)

                    lstCharacters(i) = tmp

                    Exit Sub

                End If

            Next

        End Sub

        Public Sub DrawCharacters(ByRef mode As Globals.DrawingMode, ByRef offsetX As Integer, ByRef offsetY As Integer, ByRef originX As Integer, ByRef originY As Integer, ByRef defaultZ As Single, ByRef tc As Long)

            If lstCharacters.Count = 0 Then Exit Sub

            If mode = Globals.DrawingMode.Overlay Then
                DoMovement()
            End If

            Dim c As Integer = lstCharacters.Count - 1
            'Dim tmpChar As Character



            For i As Integer = 0 To c

                If mode = Globals.DrawingMode.Overlay Then

                    'tmpChar = lstCharacters(i)
                    lstCharacters(i).DrawOverlay(offsetX, offsetY, originX, originY, defaultZ)

                ElseIf mode = Globals.DrawingMode.Shadow Then

                    lstCharacters(i).DrawShadow(mode, offsetX, offsetY, originX, originY, defaultZ + 0.001F)

                Else

                    lstCharacters(i).DrawMain(mode, offsetX, offsetY, originX, originY, defaultZ)


                End If

            Next

        End Sub

        'Public Sub DrawCharactersAtPos(ByRef mode As Globals.DrawingMode, ByRef xcoord As Integer, ByRef ycoord As Integer, ByRef xpos As Integer, ByRef ypos As Integer, ByRef z As Single, ByRef tc As Long)

        'If lstCharacters(xcoord, ycoord) Is Nothing Then Exit Sub
        'Static c As Integer
        'c = lstCharacters(xcoord, ycoord).Count - 1
        'If c = -1 Then Exit Sub

        'Static isUpdated As Boolean
        'Static tmpChar As Character

        'For i As Integer = 0 To c

        'tmpChar = lstCharacters(xcoord, ycoord)(i)

        'With tmpChar

        'If .HeadAnimObj.mCurrentAnim.mDrawMode = mode Or .HumAnimObj.mCurrentAnim.mDrawMode = mode Or mode = Globals.DrawingMode.Tinted Then

        'If mode = .HumAnimObj.mCurrentAnim.mDrawMode Then

        'DoMovement(tmpChar, tc, isUpdated)

        'If isUpdated Then lstCharacters(xcoord, ycoord)(i) = tmpChar

        'End If

        '.HumAnimObj.Visible = True

        '.HumAnimObj.Draw(mode, xpos - .MovementOffsetX, ypos - .MovementOffsetY, z)

        '.HumAnimObj.Visible = False


        'End If

        'End With

        'Next

        'End Sub

        Public Sub DoMovement()

            Dim act As Actor.MirActor

            For i As Integer = 0 To lstCharacters.Count - 1
                act = lstCharacters(i)
                act.DoMove()
                lstCharacters.RemoveAt(i)
                lstCharacters.Insert(i, act)
            Next

        End Sub

        Public Sub UpdateCharacterChat(ByRef msg As EvoLib.Protocol.CharChatMsg, ByRef tc As Long)

            'if character list is empty, exit sub-routine
            If lstCharacters.Count = 0 Then Exit Sub

            'iterate throught Actors in the Character list
            For Each Act As Actor.MirActor In lstCharacters

                'if the Name of the sender (of the chat message) matches the Actor Name THEN...
                If Act.ActorName = msg.STR_NAME Then

                    'Set the Chat Text string to the message string
                    Act.mChatText = msg.STR_NAME & ": " & msg.msg.STR_MSG
                    'set the Chat Message timeout
                    Act.mChatTimeout = tc + Constants.ChatMessageDisplayTime

                    'exit sub-routine, nothing left to do
                    Exit Sub

                End If

            Next

        End Sub

        Public Sub CharacterShapeUpdate(ByVal info As EvoLib.Protocol.CharacterShape)

            If lstCharacters.Count = 0 Then Exit Sub


            For i As Integer = 0 To lstCharacters.Count - 1

                If lstCharacters.Item(i).ActorID = info.ID_CHARACTER Then

                    Dim tmpchar As Actor.MirActor = lstCharacters.Item(i)
                    tmpchar.ShapeInfo = info.info
                    tmpchar.CalcAnim(False, True)
                    lstCharacters.RemoveAt(i)
                    lstCharacters.Add(tmpchar)

                    Exit Sub

                End If

            Next

        End Sub

        Public Sub CharacterDie(ByVal charid As Integer)

            If charid = Player.PlayerID Then

                Player.Die()

            Else

                For Each act As Actor.MirActor In lstCharacters

                    If act.ActorID = charid Then
                        Dim info As PlayerPositionInfo
                        info.INT2_X = act.mXCoord
                        info.INT2_X = act.mYCoord
                        act.Die(info)

                    End If

                Next

            End If

        End Sub

        Public Function GetCharacterFromPos(ByVal x As Integer, ByVal y As Integer) As Actor.MirActor

            For Each act As Actor.MirActor In lstCharacters

                If act.mXCoord = x And act.mYCoord = y Then
                    Return act
                End If

            Next

            Return Nothing

        End Function

        'Removes any character that has gone outside of the Play Area, e.g. 'Off-Screen'
        Public Sub FilterCharacters()

            'if there are no Characters in the list, Exit sub
            If lstCharacters.Count = 0 Then Exit Sub

            'iterate for every index in lstCharacters
            For i As Integer = 0 To lstCharacters.Count - 1
                'if we have exceeded the Count then index is invalid, so Exit the subroutine
                If i >= lstCharacters.Count Then Exit Sub

                'check if this 'i' indexed character is outside the 'Play Area'
                If lstCharacters(i).mXCoord < GameWindow.CoordX - Constants.PlayAreaX Or _
                   lstCharacters(i).mYCoord < GameWindow.CoordY - Constants.PlayAreaY Or _
                    lstCharacters(i).mXCoord > GameWindow.CoordX + Constants.PlayAreaX Or _
                    lstCharacters(i).mYCoord > GameWindow.CoordY + Constants.PlayAreaY Then

                    'Character IS outside the play area, so...

                    'Remove this character
                    RemoveCharacter(lstCharacters(i).ActorID)

                    'call self to remove further Invalidated Characters
                    FilterCharacters()
                    Exit Sub

                End If

            Next

        End Sub

        Public Sub UpdateCharacterWeight(info As PlayerWeightDesc)

            If lstCharacters.Count = 0 Then Exit Sub


            For i As Integer = 0 To lstCharacters.Count - 1

                If lstCharacters.Item(i).ActorID = info.ID_CHARACTER Then

                    Dim tmpchar As Actor.MirActor = lstCharacters.Item(i)
                    tmpchar.Weights = info.Weights
                    'tmpchar.CalcAnim(False, True)
                    lstCharacters.RemoveAt(i)
                    lstCharacters.Add(tmpchar)

                    Exit Sub

                End If

            Next

        End Sub

    End Module

End Namespace
